const xml2js = require("xml2js");

/**
 * 微信支付成功
 */
module.exports = () => {
    return async (ctx, next) => {
        const xml = await rawbody(ctx.req);
        const res = await parseXML(xml);

        const error = () => {
            ctx.status = 400
            ctx.type = 'application/xml'
            ctx.body = buildXML({
                return_code: 'FAIL',
                return_msg: 'OK',
            })
        }

        try {
            // { return_code: 'SUCCESS',
            //   return_msg: 'OK',
            //   appid: 'wx62376329cda09d92',
            //   mch_id: '1605676329',
            //   nonce_str: '4tBsDZpitxlofS76',
            //   sign: '1268BAF956806B7550AAE22B1D3D1471',
            //   result_code: 'SUCCESS',
            //   openid: 'oAPZc5ENw-3JFfd83woNwHvlTUkI',
            //   is_subscribe: 'N',
            //   trade_type: 'JSAPI',
            //   bank_type: 'OTHERS',
            //   total_fee: '1',
            //   fee_type: 'CNY',
            //   transaction_id: '4200000801202101157438358176',
            //   out_trade_no: '21011532695916',
            //   attach: '21011568477668',
            //   time_end: '20210115100318',
            //   trade_state: 'SUCCESS',
            //   cash_fee: '1',
            //   trade_state_desc: '支付成功',
            //   cash_fee_type: 'CNY'
            // }
            if (res.return_code === 'SUCCESS' && res.result_code === 'SUCCESS') {
                ctx.type = 'application/xml'
                ctx.body = buildXML({
                    return_code: 'SUCCESS',
                    return_msg: 'OK',
                });

                return res;
            }

        } catch (e) {
            console.error(e);
        }

        error();
    }
}

async function rawbody(req) {

    return new Promise((resolve, reject) => {

        var buffers = [];

        req.on('data', function(trunk) {
            buffers.push(trunk);
        });

        req.on('end', function() {
            return resolve(Buffer.concat(buffers));
        });

        req.once('error', reject);
    })
}

// XML转对象
async function parseXML(xml) {

    return new Promise((resolve, reject) => {
        var parser = new xml2js.Parser({
            trim: true,
            explicitArray: false,
            explicitRoot: false
        });

        parser.parseString(xml, function(err, result) {
            if (err) return reject(err);

            return resolve(result);
        });
    })

}

function buildXML(json) {
    var builder = new xml2js.Builder();
    return builder.buildObject({
        xml: json
    });
}